package com.yootk.action;

import com.yootk.task.YootkThreadTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("async/*")
public class AsyncAction {

    @Qualifier("asyncPoolTaskExecutor")
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;  // 获取线程池

    @Autowired
    private YootkThreadTask threadTask;     // 异步任务

    @RequestMapping("callable")
    public Object callable(String msg) {
        log.info("外部线程：{}", Thread.currentThread().getName());
        return new Callable<String>() {     // 返回一个异步线程
            @Override
            public String call() throws Exception {
                log.info("内部线程：{}", Thread.currentThread().getName());
                return "【ECHO】" + msg;
            }
        };
    }

    @RequestMapping("runnable")
    public Object runnable(String msg) {
        log.info("外部线程：{}", Thread.currentThread().getName());
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        DeferredResult<String> result = new DeferredResult<>(6000L);    // 设置超时时间
        result.onTimeout(new Runnable() {   // 超时线程
            @Override
            public void run() {
                log.info("超时线程：{}", Thread.currentThread().getName());
                result.setResult("【请求超时】" + request.getRequestURL());
            }
        });
        result.onCompletion(new Runnable() {    // 完成处理线程
            @Override
            public void run() {
                log.info("完成线程：{}", Thread.currentThread().getName());
            }
        });
        this.threadPoolTaskExecutor.execute(new Runnable() {    // 线程核心任务
            @Override
            public void run() {
                log.info("内部线程：{}", Thread.currentThread().getName());
                try {
                    TimeUnit.SECONDS.sleep(2);  // 模拟延迟
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                result.setResult("【ECHO】" + msg);   // 执行最终的响应
            }
        });
        return result;
    }

    @RequestMapping("task")
    public Object task(String msg) {
        log.info("外部线程：{}", Thread.currentThread().getName());
        this.threadTask.startTaskHandler();
        return "【ECHO】" + msg;
    }
}
